{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Scan for one port"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Connection successful\n"
     ]
    }
   ],
   "source": [
    "package main\n",
    "\n",
    "import (\n",
    "    \"fmt\"\n",
    "    \"net\"\n",
    ")\n",
    "\n",
    "func main() {\n",
    "    _, err := net.Dial(\"tcp\", \"scanme.nmap.org:80\")\n",
    "    if err == nil {\n",
    "        fmt.Println(\"Connection successful\")\n",
    "    }\n",
    "}\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# performing noconcurrent scanning\n",
    "\n",
    "TCP ports range from 1 to 65535"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 is open\n",
      "2 is open\n",
      "3 is open\n",
      "4 is open\n",
      "5 is open\n",
      "6 is open\n",
      "7 is open\n",
      "8 is open\n",
      "9 is open\n",
      "10 is open\n",
      "11 is open\n",
      "12 is open\n",
      "13 is open\n",
      "14 is open\n",
      "15 is open\n",
      "16 is open\n",
      "17 is open\n",
      "18 is open\n"
     ]
    }
   ],
   "source": [
    "for i:=1; i <= 18; i++ {\n",
    "    address := fmt.Sprintf(\"scanme.nmap.org:%d\", i)\n",
    "    connection, err := net.Dial(\"tcp\", address)\n",
    "    if err != nil {\n",
    "        // port is closed or filtered\n",
    "        continue\n",
    "    }\n",
    "    connection.Close()\n",
    "    fmt.Printf(\"%d is open\\n\", i)\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Performing noconcurrent scanning"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "443 is open\n",
      "80 is open\n",
      "2222 is open\n",
      "631 is open\n",
      "1883 is open\n",
      "1716 is open\n",
      "1089 is open\n",
      "8081 is open\n",
      "8889 is open\n",
      "8890 is open\n",
      "6379 is open\n",
      "6942 is open\n",
      "8888 is open\n",
      "9101 is open\n",
      "9100 is open\n",
      "9102 is open\n",
      "9091 is open\n",
      "15672 is open\n",
      "17699 is open\n",
      "15490 is open\n",
      "26552 is open\n",
      "27017 is open\n",
      "28282 is open\n",
      "25672 is open\n",
      "34019 is open\n",
      "35355 is open\n",
      "33395 is open\n",
      "32979 is open\n",
      "38415 is open\n",
      "38327 is open\n",
      "38187 is open\n",
      "43110 is open\n",
      "32797 is open\n",
      "40509 is open\n",
      "41371 is open\n",
      "39000 is open\n",
      "41821 is open\n",
      "40915 is open\n"
     ]
    }
   ],
   "source": [
    "package main \n",
    "\n",
    "import (\n",
    "    \"fmt\"\n",
    "    \"net\"\n",
    "    \"sync\"\n",
    ")\n",
    "\n",
    "func main() {\n",
    "    var waitGroup sync.WaitGroup\n",
    "    for i:=1; i <= 65535; i++ {\n",
    "        waitGroup.Add(1)\n",
    "        go func(j int) {\n",
    "            defer waitGroup.Done() //we call this function when this function is done(). wg.Done() will do this: waitGroup_counting -= 1\n",
    "            address := fmt.Sprintf(\"localhost:%d\", j)\n",
    "            connection, err := net.Dial(\"tcp\", address)\n",
    "            if err != nil {\n",
    "                // port is closed or filtered\n",
    "                return\n",
    "            }\n",
    "            connection.Close()\n",
    "            fmt.Printf(\"%d is open\\n\", j)\n",
    "        }(i)\n",
    "    }\n",
    "    waitGroup.Wait()\n",
    "}\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this version of the program, you create sync.WaitGroup u, which acts as a synchronized counter. \n",
    "\n",
    "You increment this counter via wg.Add(1) each time you create a goroutine to scan a port v, and a deferred call to wg.Done() decrements the counter whenever one unit of work has been performed w.\n",
    "\n",
    "Your main() function calls wg.Wait() , which blocks until all the work has been done and your counter has returned to zero x.\n",
    "\n",
    "**`cap()` tells you the capacity of the underlying array. len tells you how many items are in the array. **"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Port Scanning Using a Worker Pool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "package main \n",
    "\n",
    "import (\n",
    "    \"fmt\"\n",
    "    \"sync\"\n",
    ")\n",
    "\n",
    "func worker(ports chan int, wg *sync.WaitGroup) {\n",
    "    for p := range ports{\n",
    "        fmt.Println(p)\n",
    "        wg.Done()\n",
    "    }\n",
    "}\n",
    "\n",
    "func main() {\n",
    "    ports := make(chan int, 100)\n",
    "    var wg sync.WaitGroup\n",
    "    for i:=0; i < cap(ports); i++ {\n",
    "        go worker(ports, &wg)\n",
    "    }\n",
    "    for i := 1; i <= 1024; i++ {\n",
    "        wg.Add(1)\n",
    "        ports <- i \n",
    "    }\n",
    "    wg.Wait()\n",
    "    close(ports)\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, you create a channel by using make() v. A second parameter, an int value of 100 , is provided to make() here. This allows the channel to be buffered, which means you can send it an item without waiting for a receiver to read the item. Buffered channels are ideal for maintaining and track- ing work for multiple producers and consumers. You’ve capped the chan- nel at 100, meaning it can hold 100 items before the sender will block. This is a slight performance increase, as it will allow all the workers to\n",
    "start immediately.\n",
    "\n",
    "Next, you use a for loop w to start the desired number of workers—in this case, 100. In the worker(int, *sync.WaitGroup) function, you use range u to continuously receive from the ports channel, looping until the channel is closed. Notice that you aren’t doing any work yet in the worker—that’ll come shortly. Iterating over the ports sequentially in the main() function, you send a port on the ports channel x to the worker. After all the work has been completed, you close the channel y.\n",
    "\n",
    "Once you build and execute this program, you’ll see your numbers printed to the screen. You might notice something interesting here: the numbers are printed in no particular order. Welcome to the wonderful world of parallelism."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multichannel Version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "package main\n",
    "\n",
    "import (\n",
    "    \"fmt\"\n",
    "    \"net\"\n",
    "    \"sort\"\n",
    ")\n",
    "\n",
    "func worker(ports, results chan int) {\n",
    "    for p := range ports {\n",
    "        address := fmt.Sprintf(\"localhost:%d\", p)\n",
    "        connection, err := net.Dial(\"tcp\", address)\n",
    "        if err != nil {\n",
    "            results <- 0\n",
    "            continue\n",
    "        }\n",
    "        connection.Close()\n",
    "        results <- p\n",
    "    }\n",
    "}\n",
    "\n",
    "func main() {\n",
    "    ports := make(chan int, 10000)\n",
    "    results := make(chan int)\n",
    "    var openPorts []int\n",
    "    \n",
    "    for i:=0; i < cap(ports); i++ {\n",
    "        go worker(ports, results)\n",
    "    }\n",
    "    \n",
    "    go func() {\n",
    "        for i:=1; i <= 65535; i++ {\n",
    "            ports <- i\n",
    "        }\n",
    "    }()\n",
    "    \n",
    "    for i:=0; i < 65535; i++ {\n",
    "        port := <-results\n",
    "        if port != 0 {\n",
    "            openPorts = append(openPorts, port)\n",
    "        }\n",
    "    }\n",
    "    \n",
    "    close(ports)\n",
    "    close(results)\n",
    "    sort.Ints(openPorts)\n",
    "    for _, port := range openPorts {\n",
    "        fmt.Printf(\"%d open\\n\", port)\n",
    "    }\n",
    "}\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dial ip4:1 192.168.1.1: socket: operation not permitted\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "56 <nil>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "package GoFind\n",
    "\n",
    "import (\n",
    "\t\"fmt\"\n",
    "\t\"net\"\n",
    ")\n",
    "\n",
    "connection, err := net.Dial(\"ip4:1\", \"192.168.1.1\")\n",
    "fmt.Println(err)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Go",
   "language": "go",
   "name": "gophernotes"
  },
  "language_info": {
   "codemirror_mode": "",
   "file_extension": ".go",
   "mimetype": "",
   "name": "go",
   "nbconvert_exporter": "",
   "pygments_lexer": "",
   "version": "go1.14.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
